#!/usr/bin/env python
import urllib,requests,urllib2,socket,mechanize
from urlparse import urlsplit,urlparse,urlunparse,urljoin
from Data import Data_Access
from bs4 import BeautifulSoup

########################################################################
class PluginXSS (object):
    """
    Responsavel por montar e analisar ataques de Injecao de Codigos Script
    """    
    #----------------------------------------------------------------------
    def __init__(self):
        """
        Constructor
        """
        self.data_Access = Data_Access(2, "PL_XSS")    
        self.attack_Name = "XSS Injection"
        self.attack_Criticity = "High"        
        
    #----------------------------------------------------------------------   
    def get_Attack (self):
        """
        Retorna os ataques que estao no Banco de Dados
        """
        return self.data_Access.getAttack()
    
    
    #----------------------------------------------------------------------
    def get_Mitigation (self):
        """
        Retorna as mitigacoes que estao no Banco de Dados
        """
        return self.data_Access.getMitigation()
    
    #----------------------------------------------------------------------
    def get_Impact (self):
        """
        Retorna o nome da vulnerabilidade
        """
        return self.attack_Criticity
    
    #----------------------------------------------------------------------  
    def get_Response (self):
        """
        Retorna as respostas que estao no Banco de Dados
        """
        return self.data_Access.getResponse()
        
    #----------------------------------------------------------------------   
    def get_Vulnerability (self):
        """
        Retorna o nome da vulnerabilidade
        """
        return self.attack_Name
        

    #----------------------------------------------------------------------    
    def get_Attack_Monted (self, url):
        """
        Retorna a URL concatenada com o ataque
        """
        self.atack_monted = []
        
        for atack in self.getAttack():
            self.atack_monted.append(url + ''.join(atack))
            
        return self.atack_monted
        
    #----------------------------------------------------------------------
    def mount_URL_Attack (self, url):
        """
        Ataque via URL GET
        """
        self.url_attack_parse = urlparse(url)
        self.url_parse_base = self.url_attack_parse.scheme + "://" + self.url_attack_parse.netloc + self.url_attack_parse.path + "?"
        self.url_atributos_ataques = []
        self.atributo_ataque = []
        
        # Pega todos os atributos da URL e os separa em uma lista
        self.urls_att = []
        self.urls_att.append('&'.rpartition(self.url_attack_parse.query))
        
    #----------------------------------------------------------------------
    def gen_Form_Attack(self, list_forms, url):
        """
        Inclui no formulario o ataque
        """
        self.list_forms = []
        self.list_forms = list_forms
        
        self.list_forms_ataques = []
        
        self.aux = []
        
        for ataque in self.get_Attack():
            for formulario in self.list_forms:
                self.aux.append([formulario,''.join(ataque)])
            self.list_forms_ataques.append([url, self.aux])	
            self.aux = []
        return self.list_forms_ataques
    
    
    #---------------------------------------------------------------------- 
    def analisa_Resultado (self, html, url_ataque, atributo):
        """
        Analisa o codigo da pagina HTML se existe a presenca de Injecao de codigos Script
        """
        self.bsxss = BeautifulSoup(html, 'lxml')
        self.script = self.bsxss.find_all ('script')
        self.attack_Result = []
        
        # Verifica se existe getResponse no codigo-fonte da pagina atacada
        for resp in self.script:
            if resp.find('<script>alert(\'__XSS__\')</script>') != -1:
            
                # Concatena as informacoes retorno
                self.attack_Result.append('VULNERAVEL')
                self.attack_Result.append(self.get_Impact())
                self.attack_Result.append(url_ataque)
                self.attack_Result.append(atributo)
                self.attack_Result.append(self.get_Mitigation())
                # 1 = Ataque funcionou
                self.attack_Result.append(True)
                
            else:
                # Concatena as informacoes retorno
                self.attack_Result.append('NAO VULNERAVEL')
                self.attack_Result.append(self.get_Impact())
                self.attack_Result.append(url_ataque)
                self.attack_Result.append(atributo)
                self.attack_Result.append(self.get_Mitigation())
                # 0 = Ataque nao funcionou
                self.attack_Result.append(False)
                
            return self.attack_Result
    
    #----------------------------------------------------------------------
    def gerar_Ataques (self, url):
        """
        Ataca os parametros da URL informada
        """
        self.URL_List_Target = []
        self.URL_List_Target = url
        self.lista_ataques_gerados = []
        
        for URL_Target in self.URL_List_Target:
            self.url_attack_parse = urlparse(URL_Target)
            self.url_parse_base = self.url_attack_parse.scheme + "://" + self.url_attack_parse.netloc + self.url_attack_parse.path + "?"
            self.url_atributos_ataques = []
            self.atributo_ataque = []
            
            self.lista_var = []
            self.lista_var = self.url_attack_parse.query.split('&')
        
            # Pega todos os atributos da URL e os separa em uma lista
            for atributo in self.url_attack_parse.query.split('&'):
                self.str_var_fix = ""
                
                for var_fix in self.lista_var:
                    if var_fix == atributo:
                        pass
                    else:
                        self.str_var_fix = self.str_var_fix + "&" + var_fix
                    
               # Pega o atributo e inclui o ataque nele
                for atack in self.get_Attack():
                    self.lista_ataques_gerados.append([self.url_parse_base + atributo + ''.join(atack) + self.str_var_fix, atributo])
                      
        return self.lista_ataques_gerados